//Name: Cao Dung Anh
//Class: 11CTT
//Sid: 1151003

#include <iostream>
using namespace std;
#include <string>
#include "UserInfo.h"
#include "BookList.h"
#include "UserList.h"
#include <conio.h>

UserInfo::UserInfo()
{
}

void UserInfo::showInfo()
{
	cout << "Username:        " << this->Username << endl;
	cout << "Day of birth:    " << this->DoB.day << "/" << this->DoB.month << "/" << this->DoB.year << endl;
	cout << "Address:         " << this->Address << endl;
	cout << "Name of user:    " << this->Name << endl;
	cout << "Identify number: " << this->id << endl;
	cout << "Sex:             ";
	if(this->Sex == 0)
		cout << "Female\n";
	else
		cout << "Male\n";
	cout << "User Type:       ";
	if (this->UserType == 1)
	{
		cout << "Administrator\n";
	}
	else if(this->UserType == 2)
	{
		cout << "Librarian\n";
	}
	else
	{
		cout << "Reader\n";
	}
	cout << "Status:          ";
	if (this->Status == 0)
	{
		cout << "Inactive\n";
	}
	else if (this->Status == 1)
	{
		cout << "Active\n";
	}
	else if (this->Status == 2)
	{
		cout << "Banned\n";
	}
}

void UserInfo::addUser()
{
	char temp[10];
	string pass="";
	char *p;
	cout << "Username: ";
	cin.getline(this->Username,sizeof(this->Username));
	cout << "Password: ";

	//Change password character to "*"
	char ch;
	ch = _getch();
	while(ch != 13){//character 13 is enter
		if (ch == 8)
		{
			pass.push_back(ch);
			cout << ch;
			ch = 0;
			cout << ch;
			ch = 8;
			cout << ch;
			ch = _getch();
		}
		else
		{
			pass.push_back(ch);
			cout << '*';
			ch = _getch();
		}
	}
	cout << endl;
	p = &pass[0];
	strcpy(this->Password,p);

	this->EncryptPassword(this->Password);

	cout << "Day of Birth\n";
	cout << "\tDay: ";
	cin >> this->DoB.day;
	cout << "\tMonth: ";
	cin >> this->DoB.month;
	cout << "\tYear: ";
	cin >> this->DoB.year;
	
	cout << "ID: ";
	cin >> this->id;
	cin.get();
	cout << "Address: ";
	cin.getline(this->Address,sizeof(this->Address));
	cout << "Name of user: ";
	cin.getline(this->Name,sizeof(this->Name));
	cout << "Sex: ";
	cin >> temp;
	if (strcmp(temp,"female") || strcmp(temp,"Female"))
		this->Sex = false;
	else if(strcmp(temp,"male") || strcmp(temp,"Male"))
		this->Sex = true;
	else
		cout << "invalid input" << endl;
	cout << "UserType: ";
	cin >> this->UserType;
	cout << "Activated (0/1): ";
	cin >> this->Status;
	cin.get();
}

//Add new user with specified usertype
void UserInfo::addUser(int usertype,char *username,char *name)
{
	//cin.get();
	UserList a;
	char str[1000];
	char *p;
	string pass = "";
	int c;
	char temp[10];
	strcpy(this->Username,username);
	strcpy(this->Name,name);
	do 
	{
		c = 1;//if password inputed correctly, then this will pass the while loop
		cout << "Password: \n";
		
		//Change password character to "*"
		char ch;
		ch = _getch();
		while(ch != 13){//character 13 is enter
			if (ch == 8)
			{
				pass.push_back(ch);
				cout << ch;
				ch = 0;
				cout << ch;
				ch = 8;
				cout << ch;
				ch = _getch();
			}
			else
			{
				pass.push_back(ch);
				cout << '*';
				ch = _getch();
			}
		}
		cout << endl;
		p = &pass[0];
		strcpy(this->Password,p);

		if (!checkPassword(Password))
		{
			cout << "Invalid password, you have to insert correctly\n";
			c = 0;
		}
		//strcpy(this->Password,EncryptPassword(this->Password));
	} while (c == 0);
	this->EncryptPassword(this->Password);
	do 
	{
		c = 1;
		cout << "Day of Birth\n";
		cout << "\tDay: ";
		cin >> this->DoB.day;
		cout << "\tMonth: ";
		cin >> this->DoB.month;
		cout << "\tYear: ";
		cin >> this->DoB.year;
		if (!checkDatetime(this->DoB.day,this->DoB.month,this->DoB.year))
		{
			cout << "Invalid date-time, you have to input correctly\n";
			c = 0;
		}
	} while (c == 0);
	cin.get();
	do 
	{
		cout << "ID: ";
		cin.getline(str,sizeof(str));
		c = 1;
		if (a.isNumber(str))
		{
			this->id = a.convertStringtoNum(str);
		}
		else
		{
			cout << "Invalid ID input, you have to insert again\n";
			c = 0;
		}
	} while (c == 0);
	cout << "Address: ";
	cin.getline(this->Address,sizeof(this->Address));
	cout << "Sex: ";
	cin.getline(temp,sizeof(temp));
	if (strcmp(temp,"female")==0 || strcmp(temp,"Female")==0)
	{
		this->Sex = false;
	}
	else if(strcmp(temp,"male")==0 || strcmp(temp,"Male")==0)
	{
		this->Sex = true;
	}
	else
		cout << "invalid input" << endl;
	this->UserType = usertype;
	this->Status = 0;
	cout << "\nYou have successfully created new account\n\n";
}

void UserInfo::copyInfo(UserInfo a)
{
	strcpy(this->Username,a.Username);
	strcpy(this->Password,a.Password);
	strcpy(this->Name,a.Name);
	strcpy(this->Address,a.Address);
	this->id=a.id;
	this->DoB.day = a.DoB.day;
	this->DoB.month = a.DoB.month;
	this->DoB.year = a.DoB.year;
	this->Sex = a.Sex;
	this->UserType = a.UserType;
	this->Status = a.Status;
}

bool UserInfo::isExist(char *username)
{
	if (strcmp(this->Username,username) == 0)
		return true;
	return false;
}

//Check for the old pass
bool UserInfo::isRightPass(char *password)
{
	if (strcmp(this->Password,password) == 0)
		return true;
	return false;
}

bool UserInfo::isExist(char *username,char *pass)
{
	//strcpy(pass,EncryptPassword(pass));
	if (strcmp(this->Username,username) == 0 && strcmp(this->Password,pass) == 0)
	{
		return true;
	}
	return false;
}

int UserInfo::getUserType()
{
	return UserType;
}

int UserInfo::getStatus()
{
	return Status;
}

char* UserInfo::getUserName()
{
	return Username;
}

char* UserInfo::getName()
{
	return Name;
}

void UserInfo::changePassWord()
{
	cout << "New password: ";
	cin.getline(this->Password,sizeof(this->Password));
	//cin.get();
	return;
}

void UserInfo::banAcc()
{
	this->Status = 2;
	return;
}

//Set the status of the user account
//0:inactivate, 1:activate ; 2:banned
void UserInfo::setUserStatus( int num )
{
	this->Status = num;
}


//Make the String name normalization
char* UserInfo::normalizeName(char* str)
{
	if (str[0] == ' ')
	{
		strcpy(str,deleteSpaceAtFirstString(str));
	}
	for (int i = 0;i<strlen(str);++i)
	{
		if (str[i] == ' ')
		{
			while (str[i+1] == ' ')
			{
				for (int j = i+1;j<strlen(str)-1;++j)
				{
					str[j] = str[j+1];
				}
				str[strlen(str)-2] = NULL;
			}
		}
	}
	return str;
}

//Create username from name
char* UserInfo::createUsernamefromName(char *name)
{
	char username[100];
	int j=0;
	//get the first name
	for (int i=0;i<strlen(name);++i)
	{
		if (name[i] == ' ')
		{
			i = strlen(name);
			break;
		}
		username[j++]=name[i];
	}

	//get the first letter of the middle name and last name
	for (int i=0;i<strlen(name);++i)
	{
		if (name[i] == ' ')
		{
			username[j++] = name[i+1];
		}
	}
	username[j] = NULL;
	return username;
}

//Delete all space char if user type space char before there string
char* UserInfo::deleteSpaceAtFirstString(char *str)
{
	while (str[0] == ' ')
	{
		for (int j = 0;j<strlen(str)-1;++j)
		{
			str[j] = str[j+1];
		}
		str[strlen(str)-2] = NULL;
	}
	return str;
}

//Phuong Anh
// check the input day
bool UserInfo::checkDay(int day)
{
	if((day>31) || (day<=0))
		return false;
	else
		return true;
}

//check the input month
bool UserInfo::checkMonth(int month)
{
	if((month>12) || (month<=0))
		return false;
	else
		return true;
}

//check year
bool UserInfo::checkYear(int year)
{
	if(year<=0)
		return false;
	else
		return true;
}

//check password
bool UserInfo::checkPassword(char pass[])
{
	if((strlen(pass)<6) || (strlen(pass)>32))
		return false;
	else
		return true;
}

//check name
bool UserInfo::checkName(char name[])
{
	for (int i=0;i<strlen(name);++i)
	{
		if(((name[i]>=65)&&(name[i]<=90))||((name[i]>=97)&&(name[i]<=122))||(name[i]==32)||(name[i]==45))
			return true;
		else
			return false;
	}

}

//check user name
bool UserInfo::checkUserName(char name[])
{
	int check =0;
	for (int i=0;i<strlen(name);++i)
	{
		if(((name[i]>=65)&&(name[i]<=90))||((name[i]>=97)&&(name[i]<=122))||(name[i]==95)||((name[i]>=0)&&(name[i]<=9))||(name[i]==46))
		{
			if(name[i]==46)
				++check;
			if(check==2)
				return false;
		}
		else
			return false;
	}
	return true;
}

//Check Datetime
bool UserInfo::checkDatetime(int day, int month, int year)
{
	if(this->checkDay(day)==false)
		return false;
	if(this->checkMonth(month)==false)
		return false;
	if(this->checkYear(year)==false)
		return false;
	if(month==2)
	{
		if(day == 29)
		{
			if(!((year%4==0&&year%100!=0)||(year%400==0)))
				return false;
		}
		if (day >= 30)
		{
			return false;
		}
	}
	else
	{
		if(day==31)
		{
			if(!(month==1||month==3||month==5||month==7||month==8||month==10||month==12))
			{
				return false;
			}
		}
	}
	return true;
}

//encrypt user password
char* UserInfo::EncryptPassword(char* pass)
{
	char key[100];
	strcpy(key,pass);
	for(int j=0; j<strlen(key);++j)
	{
		for(int i=0; i<strlen(key);++i)
		{
			pass[i]=pass[i]^key[j];
		}
	}
	return pass;
}
//use to reset password
void UserInfo::setPassword( char *pass )
{
	strcpy(this->Password,EncryptPassword(pass));
}

int UserInfo::getDay()
{
	return DoB.day;
}

int UserInfo::getmonth()
{
	return DoB.month;
}

int UserInfo::getyear()
{
	return DoB.year;
}

int UserInfo::getID()
{
	return id;
}

char* UserInfo::getAddress()
{
	return Address;
}

bool UserInfo::getSex()
{
	return Sex;
}